package com.kaluli.system.repository;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

public class Term {

	private Set<Entry> entries;
	private int first;
	private int limit;
	private int number;

	public Term() {
		this.entries = new HashSet<Entry>();
		this.first = 0;
		this.limit = 0;
	}
	
	public int getFirst() {
		
		if( this.number > 0 ) {
			return this.number * this.limit;
		}
		return first;
	}

	/**
	 * 设置开始行数
	 * @param first
	 */
	public Term setFirst(int first) {
		this.first = first;
		return this;
	}

	public int getLimit() {
		return limit;
	}

	/**
	 * 设置限制条数
	 * @param limit
	 * @return
	 */
	public Term setLimit(int limit) {
		this.limit = limit;
		return this;
	}
	
	public int getNumber() {
		return number;
	}

	/**
	 * 设置页码
	 * @param number
	 * @return
	 */
	public Term setNumber(int number) {
		this.number = number;
		return this;
	}

	public Set<Entry> getEntries() {
		return entries;
	}
	
	/**
	 * 关联对象
	 * @param key
	 * @return
	 */
	public Term relation(String key){
		this.relation(key, key);
		return this;
	}
	
	/**
	 * 关联对象
	 * @param key
	 * @return
	 */
	public Term relation(String key , String value){
		this.put(key, value, Type.relation);
		return this;
	}

	/**
	 * in 查询 
	 * @param prop
	 * @param values
	 * @return
	 */
	public Term in(String prop, Collection values) {
		this.put(prop, values, Type.in);
		return this;
	}
	
	/**
	 * 相等 	= 
	 * @param key
	 * @param value
	 * @return
	 */
	public Term eq(String key, Object value) {
		this.put(key, value, Type.eq);
		return this;
	}

	/**
	 * 大于	同  >
	 * @param key
	 * @param value
	 * @return
	 */
	public Term gt(String key, Object value) {
		this.put(key, value, Type.gt);
		return this;
	}

	/**
	 * 大于等于   >=
	 * @param key
	 * @param value
	 * @return
	 */
	public Term gte(String key, Object value) {
		this.put(key, value, Type.gte);
		return this;
	}

	/**
	 * 小于    同    < 
	 * @param key
	 * @param value
	 * @return
	 */
	public Term lt(String key, Object value) {
		this.put(key, value, Type.lt);
		return this;
	}

	/**
	 * 小于等于	同  <=
	 * @param key
	 * @param value
	 * @return
	 */
	public Term lte(String key, Object value) {
		this.put(key, value, Type.lte);
		return this;
	}

	/**
	 * 模糊查询
	 * @param key
	 * @param value
	 * @return
	 */
	public Term like(String key, String value) {
		this.put(key, value, Type.like);
		return this;
	}
	
	/**
	 * 模糊查询
	 * @param key
	 * @param value
	 * @return
	 */
	public Term filter(String key, String value) {
		this.put(key, value, Type.filter);
		return this;
	}

	/**
	 * 排序  正序
	 * @param key
	 * @return
	 */
	public Term asc(String key) {
		this.put(key, true, Type.order);
		return this;
	}
	
	/**
	 * 排序 倒序
	 * @param key
	 * @return
	 */
	public Term desc(String key) {
		this.put(key, false , Type.order);
		return this;
	}
	
	public boolean isPageable(){
		return this.limit > 0;
	}

	protected void put(String key, Object value, Type type) {
		this.entries.add(new Entry(key, value, type));
	}

	public static Term query() {
		Term map = new Term();
		return map;
	}

	enum Type {
		eq, lt, lte, gt, gte, in, like, order , filter , relation ;
	}

	public class Entry {

		private String name;
		private Object value;
		private Type type;

		public Entry(String name, Object value, Type type) {
			this.name = name;
			this.value = value;
			this.type = type;
		}

		public String getName() {
			return name;
		}

		public Object getValue() {
			return value;
		}

		public <T> T getObject() {
			return (T) this.value;
		}

		public Type getType() {
			return type;
		}

		@Override
		public int hashCode() {
			int hash = 3377 * 11 + name.hashCode() + type.hashCode();
			return hash;
		}

		@Override
		public boolean equals(Object obj) {

			if (obj == null) {
				return false;
			}
			if (obj instanceof Entry) {
				Entry e = (Entry) obj;
				return this.name == e.name && this.type == e.type;
			}
			return false;
		}
	}

}
